package com.ningxun.pagent.bus.service.aichat.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ningxun.pagent.bus.domain.aichat.*;
import com.ningxun.pagent.common.utils.spring.SpringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ningxun.pagent.bus.domain.BusPolicyContent;
import com.ningxun.pagent.bus.domain.Response;
import com.ningxun.pagent.bus.domain.wechatuser.UserConversationFavorite;
import com.ningxun.pagent.bus.mapper.BaseAIChatMapper;
import com.ningxun.pagent.bus.service.IBusPolicyContentService;
import com.ningxun.pagent.bus.service.basewechatuser.IUserConversationFavoriteService;
import com.ningxun.pagent.common.utils.SecurityUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.reactive.function.client.WebClient;
import com.ningxun.pagent.bus.service.aichat.IBaseAIChatService;
import org.springframework.http.MediaType;
import reactor.core.publisher.Flux;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BaseAIChatServiceImpl extends ServiceImpl<BaseAIChatMapper, BaseAIChat> implements IBaseAIChatService {

    //    private String url ="http://127.0.0.1:83/v1/chat-messages";
    //    private  String difyToken = "app-M0J7hItq9etusUEW1TiNBZEg";
    private static final Logger logger = LoggerFactory.getLogger(BaseAIChatServiceImpl.class);
    @Value("${wechat.baseurl:''}")
    private String baseurl;
    @Value("${wechat.difyToken:''}")
    private String difyToken;
    @Autowired
    private WebClient webClient;
    @Autowired
    private IUserConversationFavoriteService iUserConversationFavoriteService;
    @Autowired
    private IBusPolicyContentService busPolicyContentService;

    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUserConversationFavoriteService userConversationFavoriteService;
    // 添加成员变量

    @Override
    public Flux<String> chatMessages(ChatRequest payload) {

        Long userId = SecurityUtils.getUserId();
        if (userId != null) {
            System.out.println("userid=======================" + userId);
        }

        // 创建聊天记录实体
        //存储用户说的问题
        BaseAIChat UserchatRecord = new BaseAIChat();
        //这里实际上存的是openid
        payload.setUser(SecurityUtils.getUsername());
        payload.setResponse_mode(Response.STREAMING.getValue());
        UserchatRecord.setUsercontent(payload.getQuery());;
        UserchatRecord.setUserId(payload.getUser());
        UserchatRecord.setConversationTitle(payload.getConversationTitle());
        UserchatRecord.setCreatedTime(LocalDateTime.now());
        // 用于累积响应内容
        StringBuilder conversationId = new StringBuilder();
//        StringBuilder responseContent = new StringBuilder();
        // 用于累积真正的AI回答
        StringBuilder aiAnswer = new StringBuilder();

        return webClient.post()
                .uri(baseurl + Response.CHATMESSAGE.getValue())
                .contentType(MediaType.APPLICATION_JSON)
                .header(Response.AUTHORIZATION.getValue(), Response.BEARER.getValue() + difyToken)
                .bodyValue(payload)
                .retrieve()
                .bodyToFlux(String.class)
                .filter(chunk -> {
                    // 过滤掉空的或无效的数据块
                    return chunk != null && !chunk.trim().isEmpty();
                })
                .doOnNext(chunk -> {
                    try {
                        // 解析JSON块以识别事件类型
//                        JsonNode jsonNode = objectMapper.readTree(chunk);
//                        String event = jsonNode.path("event").asText();

                        JSONObject jsonObject = JSON.parseObject(chunk);
                        String event = jsonObject.getString("event");

                        // 根据事件类型处理不同内容
                        handleEventBasedOnType(jsonObject, event, aiAnswer, conversationId);

                    } catch (Exception e) {
                        // 如果不是有效的JSON，直接处理
//                        System.out.println("===========================Non-JSON chunk: ==============" + chunk);
                    }
//                    responseContent.append(chunk);
                })
                .doOnComplete(() -> {
                    // 保存完整的响应和AI回答到数据库
//                    UserchatRecord.setSyscontent(truncateContentForDatabase(responseContent.toString()));
                    UserchatRecord.setSyscontent(truncateContentForDatabase(aiAnswer.toString()));

                    if (conversationId.length() > 0) {
                        UserchatRecord.setConversationId(conversationId.toString());
                    }

                    UserConversationFavorite userConversationFavorite = new UserConversationFavorite();
                    userConversationFavorite.setIsFavorite(false);
                    userConversationFavorite.setCreatedTime(LocalDateTime.now());
                    userConversationFavorite.setUserId(userId);
                    userConversationFavorite.setConversationId(conversationId.toString());
//                    saveChatData(UserchatRecord , userConversationFavorite);
                    // 使用SpringUtils获取AOP代理对象来确保事务生效
                    BaseAIChatServiceImpl self = applicationContext.getBean(BaseAIChatServiceImpl.class);
                    self.saveChatData(UserchatRecord, userConversationFavorite);
                });

    }

    @Transactional(rollbackFor = Exception.class)
    public void saveChatData(BaseAIChat UserchatRecord, UserConversationFavorite userConversationFavorite) {
        // 注意事务失效的场景
        SpringUtils.getAopProxy(this).save(UserchatRecord);
        //判断在收藏表中是否存在conversation_id，如果存在就不再进行插入，如果不存在就执行插入
        LambdaQueryWrapper<UserConversationFavorite> wrapper = new LambdaQueryWrapper<UserConversationFavorite>()
                .eq(UserConversationFavorite::getConversationId , userConversationFavorite.getConversationId());
        UserConversationFavorite userFavorite = iUserConversationFavoriteService.getOne(wrapper);
        if (ObjectUtils.isEmpty(userFavorite)) {
            iUserConversationFavoriteService.save(userConversationFavorite);
        }
    }

    /**
     * 根据事件类型处理不同的内容
     */
    private void handleEventBasedOnType(JSONObject jsonObject, String event,
                                        StringBuilder aiAnswer, StringBuilder conversationId) {

        // 提取conversation_id（如果存在）
//        String convId = jsonNode.path("conversation_id").asText();
        String convId = jsonObject.getString("conversation_id");
        if (!convId.isEmpty() && conversationId.length() == 0) {
            conversationId.append(convId);
        }

        // 根据不同事件类型处理
        switch (event) {
            case "message":
            case "agent_message":
            case "text_chunk":
                // 这些事件通常包含AI的回答内容
//                String answer = jsonNode.path("data").path("text").asText();
                String answer = jsonObject.getJSONObject("data").getString("text");
                if (!answer.isEmpty()) {
                    aiAnswer.append(answer);
                    System.out.println("AI Answer chunk: " + answer);
                }
                break;

            case "workflow_finished":
                // 工作流完成时可能包含最终结果
//                String result = jsonNode.path("data").path("outputs").path("result").asText();
                String result = jsonObject.getJSONObject("data").getJSONObject("outputs").getString("result");
                if (!result.isEmpty()) {
                    aiAnswer.append(result);
                    System.out.println("Final result: " + result);
                }
                break;

            case "node_finished":
                // 节点完成时可能包含输出
//                JsonNode outputs = jsonNode.path("data").path("outputs");
                JSONObject outputs = jsonObject.getJSONObject("data").getJSONObject("outputs");
                if (!outputs.isEmpty()) {
                    // 检查是否有answer或response字段
//                    String nodeAnswer = outputs.path("answer").asText();
                    String nodeAnswer = outputs.getString("answer");
                    if (nodeAnswer.isEmpty()) {
//                        nodeAnswer = outputs.path("response").asText();
                        nodeAnswer = outputs.getString("response");
                    }
                    if (!nodeAnswer.isEmpty()) {
                        aiAnswer.append(nodeAnswer);
                        System.out.println("Node answer: " + nodeAnswer);
                    }
                }
                break;

            default:
                // 其他事件类型，暂时不处理
                System.out.println("Unhandled event type: " + event);
                break;
        }
    }
    /*
    防止溢出
     */
    private String truncateContentForDatabase(String content) {
        if (content == null) {
            return null;
        }
        int maxLength = 65535; // TEXT类型最大长度
        if (content.length() <= maxLength) {
            return content;
        } else {
            return content.substring(0, maxLength - 3) + "...";
        }
    }

    /**
     * 获得回答的政策来源
     *
     */
    @Override
    public List<BusPolicyContent> getResId(Query query){
        query.setUser(SecurityUtils.getUsername());
        query.setResponse_mode(Response.BLOCKING.getValue());
        JSONObject block = webClient
                .post()
                .uri(baseurl + Response.WECHATFLOW.getValue())
                .contentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE))
                .header(Response.AUTHORIZATION.getValue(), Response.BEARER.getValue() + Response.FLOWTOKEN.getValue())
                .bodyValue(query)
                .retrieve()
                .bodyToMono(JSONObject.class)
                .block();
        JSONArray titles = block.getJSONObject("data").getJSONObject("outputs").getJSONArray("result");

        List<Title> items = JSON.parseArray(titles.toJSONString(), Title.class);
        // 提取title字段
        List<String> titleList = items.stream()
                .map(Title::getTitle)
                .collect(Collectors.toList());
        return getPolicyContent(titleList);
    }

    private List<BusPolicyContent> getPolicyContent(List<String> ids){
        List<Long> longList = Convert.toList(Long.class, ids);
        List<BusPolicyContent> busPolicyContentsList = busPolicyContentService.selectBusPolicyContentByPolicyIdList(longList);
        return busPolicyContentsList;
    }

    /**
     * 新增根据上下文预测用户的问题：
     *
     */
    @Override
    public List<Question> getQuery(Query beginQuery){

        beginQuery.setUser(SecurityUtils.getUsername());
        beginQuery.setResponse_mode(Response.BLOCKING.getValue());
        JSONObject response = webClient
                .post()
                .uri(baseurl + Response.WECHATFLOW.getValue())
                .contentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE))
                .header(Response.AUTHORIZATION.getValue(), Response.BEARER.getValue() + Response.QUERYTOKEN.getValue())
                .bodyValue(beginQuery) // 自动序列化为JSON
                .retrieve()
                .bodyToMono(JSONObject.class)
                .block();
        String questionString = response.getJSONObject("data").getJSONObject("outputs").getString("text");
        String substring = questionString.substring(27, questionString.length() - 10);
        String[] split = substring.split(",");
        List<Question> questionList = new ArrayList<>();
        for (String item : split) {
            Question question = new Question(item.substring(3));
            questionList.add(question);
        }
//        List<Question> questions = JSON.parseArray(questionString.substring(8, questionString.length() - 8), Question.class);
//        Question question = JSON.parseObject(questionString.substring(25, questionString.length() - 10), Question.class);
        return questionList;

    }

    @Override
    public boolean evaluateChat(UserConversationFavorite userConversationFavorite) {
        LambdaUpdateWrapper<UserConversationFavorite> wrapper = new LambdaUpdateWrapper<>();
        if (userConversationFavorite.getConversationId() == null){
            throw new IllegalArgumentException("Invalid parameters: userConversationFavorite or conversationId cannot be null");
        }
        wrapper.set(userConversationFavorite.getUserComment() != null,
                        UserConversationFavorite::getUserComment,
                        userConversationFavorite.getUserComment())
                .set(userConversationFavorite.getIsFavorite() != null,
                        UserConversationFavorite::getIsFavorite,
                        userConversationFavorite.getIsFavorite())
                .set(userConversationFavorite.getStarRating() != null,
                        UserConversationFavorite::getStarRating,
                        userConversationFavorite.getStarRating())
                .eq(UserConversationFavorite::getConversationId,
                        userConversationFavorite.getConversationId());

        return userConversationFavoriteService.update(wrapper);

    }

    @Autowired
    private BaseAIChatMapper baseAIChatMapper;

    /**
     * 查询消息
     *
     * @param messageId 消息主键
     * @return 消息
     */
    @Override
    public BaseAIChat selectBaseAIChatByMessageId(Long messageId)
    {
        return baseAIChatMapper.selectBaseAIChatByMessageId(messageId);
    }

    /**
     * 查询消息列表
     *
     * @param baseAIChat 消息
     * @return 消息
     */
    @Override
    public List<BaseAIChat> selectBaseAIChatList(BaseAIChat baseAIChat)
    {
        return baseAIChatMapper.selectBaseAIChatList(baseAIChat);
    }

    /**
     * 新增消息
     *
     * @param baseAIChat 消息
     * @return 结果
     */
    @Override
    public int insertBaseAIChat(BaseAIChat baseAIChat)
    {
        return baseAIChatMapper.insertBaseAIChat(baseAIChat);
    }

    /**
     * 修改消息
     *
     * @param baseAIChat 消息
     * @return 结果
     */
    @Override
    public int updateBaseAIChat(BaseAIChat baseAIChat)
    {
        return baseAIChatMapper.updateBaseAIChat(baseAIChat);
    }

    /**
     * 批量删除消息
     *
     * @param messageIds 需要删除的消息主键
     * @return 结果
     */
    @Override
    public int deleteBaseAIChatByMessageIds(Long[] messageIds)
    {
        return baseAIChatMapper.deleteBaseAIChatByMessageIds(messageIds);
    }

    /**
     * 删除消息信息
     *
     * @param messageId 消息主键
     * @return 结果
     */
    @Override
    public int deleteBaseAIChatByMessageId(Long messageId)
    {
        return baseAIChatMapper.deleteBaseAIChatByMessageId(messageId);
    }

}

